# Django 快捷函数：用于渲染模板并返回 HTTP 响应
from django.shortcuts import render

# Django 分页工具：用于处理数据分页
from django.core.paginator import Paginator  # 分页器类，将查询集分页
from django.core.paginator import EmptyPage  # 页码超出范围时抛出的异常
from django.core.paginator import PageNotAnInteger  # 页码非整数时抛出的异常

# 导入当前应用的模型
from .models import *

# HTTP 响应工具：用于返回 JSON 格式的响应
from django.http import JsonResponse

# 数据库表达式：用于执行原子性更新操作（避免并发问题）
from django.db.models import F


def detailView(request, id):
    """
    商品详情页视图函数
    - 获取指定ID的商品详情
    - 获取销量前五的相关商品
    - 检查商品是否被当前用户收藏
    """
    title = '商品介绍'  # 页面标题
    classContent = 'datails'  # 页面分类标识

    # 查询指定ID的商品，若无则返回None
    commoditys = CommodityInfos.objects.filter(id=id).first()

    # 查询除当前商品外，按销量排序的前5个商品（推荐商品）
    items = CommodityInfos.objects.exclude(id=id).order_by('-sold')[:5]

    # 从session中获取用户收藏列表
    likesList = request.session.get('likes', [])

    # 判断当前商品是否被用户收藏
    likes = True if id in likesList else False

    # 将变量传递给模板渲染
    return render(request, 'details.html', locals())


def commodityView(request):
    """
    商品列表页视图函数
    - 支持分类筛选、排序和搜索
    - 实现分页功能
    """
    title = '商品列表'  # 页面标题
    classContent = 'commoditys'  # 页面分类标识

    # 生成商品分类列表（一级分类去重）
    firsts = Types.objects.values('firsts').distinct()
    typesList = Types.objects.all()

    # 获取请求参数：
    # - t: 分类ID（筛选商品类型）
    # - s: 排序字段（默认按销量排序）
    # - p: 当前页码（默认第1页）
    # - n: 搜索关键词
    t = request.GET.get('t', '')
    s = request.GET.get('s', 'sold')
    p = request.GET.get('p', 1)
    n = request.GET.get('n', '')

    # 初始化商品查询集
    commodityInfos = CommodityInfos.objects.all()

    # 根据参数筛选商品
    if t:
        # 根据分类ID筛选商品
        types = Types.objects.filter(id=t).first()
        commodityInfos = commodityInfos.filter(types=types.seconds)
    if s:
        # 根据指定字段排序（添加负号表示降序）
        commodityInfos = commodityInfos.order_by('-' + s)
    if n:
        # 根据关键词模糊搜索商品名称
        commodityInfos = commodityInfos.filter(name__contains=n)

    # 分页处理（每页6条记录）
    paginator = Paginator(commodityInfos, 6)
    try:
        pages = paginator.page(p)  # 获取指定页的数据
    except PageNotAnInteger:
        pages = paginator.page(1)  # 页码非整数时，返回第1页
    except EmptyPage:
        pages = paginator.page(paginator.num_pages)  # 页码超出范围时，返回最后一页

    return render(request, 'commodity.html', locals())


def collectView(request):
    """
    商品收藏视图函数（AJAX接口）
    - 处理用户收藏商品请求
    - 更新商品收藏数量
    - 记录用户收藏状态到session
    """
    # 获取商品ID参数
    id = request.GET.get('id', '')
    result = {"result": "已收藏"}  # 默认返回结果

    # 获取用户收藏列表（从session中）
    likes = request.session.get('likes', [])

    # 若ID有效且未收藏过该商品
    if id and not int(id) in likes:
        # 使用F表达式原子性地增加商品收藏数（避免并发问题）
        CommodityInfos.objects.filter(id=id).update(likes=F('likes') + 1)

        # 更新返回结果
        result['result'] = "收藏成功"

        # 将商品ID添加到用户收藏列表并保存到session
        request.session['likes'] = likes + [int(id)]

    # 返回JSON响应
    return JsonResponse(result)